home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <netdb.h>
- #include "dnsconf.h"
- #include "internal.h"
- #include "../dialog/dialog.h"
- #include "../xconf/xconf.h"
- #include "../userconf/userconf.h"
- #include "../paths.h"
- #include "dnsconf.m"
-
- static DNSCONF_HELP_FILE help_resolv ("resolv");
- static DNSCONF_HELP_FILE help_host_conf ("host.conf");
- static CONFIG_FILE f_resolv (ETC_RESOLV_CONF,help_resolv
- ,CONFIGF_MANAGED|CONFIGF_OPTIONNAL);
- static CONFIG_FILE f_host_conf (ETC_HOST_CONF,help_host_conf
- ,CONFIGF_MANAGED|CONFIGF_OPTIONNAL);
-
- PRIVATE void RESOLV::parse (const char *pt)
- {
- int nb = 0;
- while (*pt != '\0'){
- pt = str_skip(pt);
- char word[200];
- pt = str_copyword(word,pt);
- if (word[0] == '\0') break;
- if (nb == MAX_SEARCH_RESOLV){
- xconf_error (MSG_U(E_TOOMSEARCH
- ,"Too many entries in search statement\n"
- "in file %s")
- ,ETC_RESOLV_CONF);
- break;
- }
- search[nb++].setfrom (word);
- }
- }
-
- PUBLIC RESOLV::RESOLV()
- {
- FILE *fin = f_resolv.fopen("r");
- if (fin != NULL){
- char buf[300];
- int noline = 0;
- int nbservers = 0;
- while (fgets(buf,sizeof(buf),fin)!= NULL){
- char key[100];
- char *pt = str_copyword(key,str_skip(buf));
- noline++;
-
- /* #Specification: netconf / resolv.conf / comment
- netconf do not preserve, nor show, comments in
- /etc/resolv.conf. I am not even sure if they
- are allowed.
- */
- if (key[0] != '\0' && key[0] != '#'){
- pt = str_skip(pt);
- int err = 1;
- if (*pt != '\0'){
- err = 0;
- str_strip (pt,pt);
- if (strcmp(key,"domain")==0){
- domain.setfrom (pt);
- }else if (strcmp(key,"search")==0){
- parse (pt);
- }else if (strcmp(key,"nameserver")==0){
- servers[nbservers++].setfrom(pt);
- }else{
- err = 1;
- }
-
- }
- if (err){
- xconf_error (MSG_U(E_IVLDLINE,"Invalid line %d in %s")
- ,noline,ETC_RESOLV_CONF);
- }
- }
- }
- fclose (fin);
- }
- }
-
- PUBLIC int RESOLV::write ()
- {
- int ret = -1;
- FILE *fout = f_resolv.fopen ("w");
- if (fout != NULL){
- if (!domain.is_empty()) fprintf (fout,"domain %s\n"
- ,domain.get());
- const char *ctl = "search %s";
- const char *endctl = "";
- for (int i=0; i<MAX_SEARCH_RESOLV; i++){
- if (!search[i].is_empty()){
- fprintf (fout,ctl,search[i].get());
- ctl = " %s";
- endctl = "\n";
- }
- }
- fputs (endctl,fout);
- for (i=0; i<3; i++){
- if (servers[i].is_valid()){
- fprintf (fout,"nameserver %s\n"
- ,servers[i].get());
- }
- }
- ret = fclose (fout);
- }
- return ret;
- }
- static const char DNSCONF[]="DNSCONF";
- static const char DNSNEEDED[]="dnsneeded";
-
- void dnsconf_editresolv()
- {
- RESOLV res;
- DIALOG dia;
- char dnsneeded = (char)linuxconf_getvalnum (DNSCONF,DNSNEEDED,1);
- dia.newf_chk (MSG_U(F_DNSNEEDED,"DNS usage"),dnsneeded
- ,MSG_U(M_DNSNEEDED,"DNS is required for normal operation"));
- dia.newf_str (MSG_U(F_DEFDOM,"default domain"),res.domain);
- dia.newf_str (MSG_U(F_NAMESERV1,"nameserver 1"),res.servers[0]);
- dia.newf_str (MSG_U(F_NAMESERV2,"nameserver 2 (opt)"),res.servers[1]);
- dia.newf_str (MSG_U(F_NAMESERV3,"nameserver 3 (opt)"),res.servers[2]);
- for (int i=0; i<MAX_SEARCH_RESOLV; i++){
- char buf[100];
- sprintf (buf,MSG_U(F_SEARCHDOM,"search domain %d (opt)"),i+1);
- dia.newf_str (buf,res.search[i]);
- }
- int nofield = 0;
- while (1){
- if (dia.edit (
- MSG_U(T_RESOLVCONF,"Resolver configuration")
- ,MSG_U(I_RESOLVCONF
- ,"You can specify which name server will be used\n"
- "to resolv host ip number. Using the DNS is\n"
- "to handle this on a TCP/IP network. The others\n"
- "are the local /etc/hosts file\n"
- " (see \"information about other hosts\" menu\n"
- "or the NIS system\n")
- ,help_resolv.getpath()
- ,nofield) != MENU_ACCEPT){
- break;
- }else{
- /* We must validate the input somehow */
- SSTRING error;
- for (int n=0; n<3; n++){
- IP_ADDR *s = res.servers + n;
- if (!s->is_empty()
- && !s->is_valid()){
- char msg[100];
- sprintf (msg,MSG_U(E_IVLDIP
- ,"Invalid IP number for nameserver %d\n"),n+1);
- error.append (msg);
- }
- }
- if (error.is_empty()){
- if (res.write() != -1){
- linuxconf_replace (DNSCONF,DNSNEEDED,dnsneeded);
- linuxconf_save();
- break;
- }
- }else{
- xconf_error (error.get());
- }
- }
- }
- }
-
- /*
- Return != 0 if there is at least one nameserver specified in
- /etc/resolv.conf (IsReSoLv Configured).
-
- The resolver will use 127.0.0.1 if there is no nameserver entry, but
- some routine of linuxconf may assume that if there is no explicit
- nameserver, then this machine does not have one running either.
-
- This function also check if the DNS is really needed for normal
- operation of the computer. It will return 0 if the DNS is not needed.
- */
- int dnsconf_isrslconf()
- {
- int ret = 0;
- if (linuxconf_getvalnum (DNSCONF,DNSNEEDED,1)){
- RESOLV res;
- for (unsigned i=0; i<sizeof(res.servers)/sizeof(res.servers[0]); i++){
- if (!res.servers[i].is_empty()){
- ret = 1;
- break;
- }
- }
- }
- return ret;
- }
-
- // Do not translate
- static const char *tborder[]={
- "hosts, nis, bind",
- "hosts, nis",
- "hosts, bind, nis",
- "hosts, bind",
- "hosts",
- "nis, hosts, bind",
- "nis, hosts",
- "nis, bind, hosts",
- "nis, bind",
- "nis",
- "bind, hosts, nis",
- "bind, hosts",
- "bind, nis, hosts",
- "bind, nis",
- "bind",
- NULL,
- };
-
- /*
- Do a string compare but compare only visible char (> ' ')
- */
- static int dnsconf_strcmp(const char *str1, const char *str2)
- {
- int ret = -1;
- while (1){
- str1 = str_skip(str1);
- str2 = str_skip(str2);
- if (*str1 == *str2){
- if (*str1 == '\0'){
- ret = 0;
- break;
- }else{
- str1++;
- str2++;
- }
- }else{
- ret = *str1 - *str2;
- break;
- }
- }
- return ret;
- }
-
-
- /*
- Read /etc/host.conf
- */
- static void dnsconf_readhostconf (
- char &multi, // Tell if the "multi" statement was seen
- char &order) // Will contain an index into tborder[]
- {
- FILE *fin = f_host_conf.fopen ("r");
- multi = 0;
- order = 0;
- if (fin != NULL){
- char buf[300];
- int noline = 0;
- while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- noline++;
- char key[300];
- char *pt = str_copyword (key,buf);
- if (strcmp(key,"multi")==0){
- multi = 1;
- }else if (strcmp(key,"order")==0){
- for (int i=0; tborder[i] != NULL; i++){
- if (dnsconf_strcmp(tborder[i],pt)==0){
- order = i;
- break;
- }
- }
- }else{
- xconf_error (MSG_U(E_IVLDKEYW
- ,"Invalid keyword %s\n"
- "in file %s, line %d")
- ,key,f_host_conf.getpath()
- ,noline);
- }
- }
- fclose (fin);
- }
- }
- /*
- Write /etc/host.conf
- */
- static void dnsconf_writehostconf (
- char multi, // Tell if the "multi" statement was seen
- char order) // Will contain an index into tborder[]
- {
- FILE *fout = f_host_conf.fopen ("w");
- if (fout != NULL){
- fprintf (fout,"order %s\n",tborder[order]);
- if (multi) fputs ("multi on\n",fout);
- fclose (fout);
- }
- }
-
- /*
- Edit the file /etc/host.conf
- */
- void dnsconf_editorder()
- {
- char multi;
- char order;
- dnsconf_readhostconf(multi,order);
- DIALOG dia;
-
- dia.newf_chk ("",multi,MSG_U(F_MULTI,"Multiple IPs for one host"));
- dia.newf_title ("","");
- // User friendy version of tborder. It must have the same
- // order, line by line. "bind" just mean nothing to most people.
- static const char *tborder_v[]={
- "hosts, NIS, dns",
- "hosts, NIS",
- "hosts, dns, NIS",
- "hosts, dns",
- "hosts",
- "NIS, hosts, dns",
- "NIS, hosts",
- "NIS, dns, hosts",
- "NIS, dns",
- "NIS",
- "dns, hosts, NIS",
- "dns, hosts",
- "dns, NIS, hosts",
- "dns, NIS",
- "dns",
- NULL
- };
- for (int i=0; tborder_v[i] != NULL; i++){
- dia.newf_radio ("",order,i,tborder_v[i]);
- }
- while (1){
- if (dia.edit (MSG_U(T_NAMESERV,"Name service access")
- ,MSG_U(I_NAMESERV
- ,"You must tell the system in which order\n"
- "the various name services must be probed\n"
- "\n"
- "hosts mean /etc/hosts is probed\n"
- "NIS stand for Network Information System\n"
- "dns stands for Domain Name Service\n")
- ,help_host_conf.getpath()
- ,0)!=MENU_ACCEPT){
- break;
- }else{
- if (perm_rootaccess(MSG_U(P_WRITEHOSTS,"write /etc/host.conf"))){
- dnsconf_writehostconf (multi,order);
- break;
- }
- }
- }
- }
-
-